Tutorial 4: visualizing bees
In this tutorial, you will learn how to use the contourplot_bees from the beeoptimal.plotting module. As its name suggests, the function allows plotting the positions of one or more bees over the function landscape.
For its basic usage, contourplot_bees requires the two following key inputs:
function: The objective function you are optimizing, provide as aBenchmarkFunctionobject.bee_colony: A list of bees to plot (e.g., optimal bee or the entire colony at a given iteration).
Additional optional parameters can be specified to customize the plot, such as title, figsize, bounds, zoom, bee_marker_size, and optimal_solution.
[2]:
from beeoptimal.benchmarks import Schwefel2d
from beeoptimal.plotting import contourplot_bees
from beeoptimal import ArtificialBeeColony
Before plotting the bees, we need to optimize first our function (check the previous tutorial for details).
[3]:
ABC = ArtificialBeeColony(
colony_size = 100,
function = Schwefel2d.fun,
bounds = Schwefel2d.bounds
)
ABC.optimize(
max_iters = 1000,
mutation = 'ABC/best/1',
stagnation_tol = 1e-6,
verbose = True,
random_seed = 12345)
Running Optimization: 2%|▏ |[00:00<00:05]
Early termination: Optimization stagnated at iteration 19 / 1000
One thing we might want to do is to visualize the optimal bee at the end of the optimization process:
[4]:
contourplot_bees(
function = Schwefel2d,
bee_colony = [ABC.optimal_bee],
title = 'Optimal Bee after ABC optimization',
)
Alternatively, we might want to visualize the entire colony at a given iteration. In the example below, we visualize the colony at initialization
[5]:
contourplot_bees(
function = Schwefel2d,
bee_colony = ABC.colony_history[0],
title = f"{Schwefel2d.name} contourplot with bees",
figsize = (600,600),
bounds = None,
zoom = 1.05,
bee_marker_size = 55,
optimal_solution = ABC.optimal_bee.position
)
Finally, we can use this function in a more sophisticated way in order to visualize the entire optimization process as animated gif.
[6]:
from PIL import Image
from IPython.display import Image as IPImage
from io import BytesIO
plots = []
# Adaptive step in order to have gifs with same number of frames
step = max(1, (ABC.actual_iters+1) // 50) #Note: actual_iters +1 to include initial population
for iteration in range(0,(ABC.actual_iters+1),step):
plots.append(
contourplot_bees(
function = Schwefel2d,
bee_colony = ABC.colony_history[iteration],
title = f"{Schwefel2d.name.upper()} optimization [Iteration {iteration} / {ABC.actual_iters}]",
optimal_solution = Schwefel2d.optimal_solution,
bounds = None,
zoom = 1.05,
bee_marker_size = 55,
figsize =(500,500)
))
images = []
for fig in plots:
# Save each figure to a BytesIO object in memory instead of a file
img_buf = BytesIO()
fig.write_image(img_buf, format="png", scale=1.5) # Save the Plotly figure as PNG into the buffer
img_buf.seek(0) # Rewind the buffer to the start
images.append(Image.open(img_buf)) # Open the image from the buffer
# Create the GIF
gif_path = '../_static/animated_optimization.gif'
images[0].save(gif_path, save_all=True, append_images=images[1:], duration=200, loop=0)
IPImage(url=gif_path)
[6]:
